<template>
  <view class="quick-wrapper">
    <view>
      <view class="quick-money">
        <text class="quick-title">收款金额</text>
        <view class="quick-input">
          <view class="quick-number">{{ vdata.payAmount }}</view>
          <text>（元）</text>
        </view>
      </view>
      <view class="quick-remarks-wrapper"><text class="quick-remarks" @tap="jeepayPopupInputRef.open()">添加备注</text></view>
    </view>

    <!-- 键盘页面 -->
    <JKeyboard @selectedStore="selectedStore" @boardDown="boardDown" v-model:value="vdata.payAmount" :storeName="vdata.store.storeName" />
  </view>

  <!-- 备注弹层 -->
  <JeepayPopupInput ref="jeepayPopupInputRef" label="备注" :maxLength="12" v-model:value="vdata.payRemark" />
  <PaymentSuccess ref="paymentSuccessRef" @close="resetData" />

  <JeepayBizinfoSelect ref="jeepayBizinfoSelect" />
</template>

<script setup>
import { ref, reactive } from 'vue'
import { onUnload, onShow } from '@dcloudio/uni-app'
import PaymentSuccess from './components/PaymentSuccess.vue'
import { req, reqLoad, API_URL_MCH_STORE_LIST, $appPay, API_URL_PAY_ORDER_LIST } from '@/http/apiManager.js'
import infoBox from '@/commons/utils/infoBox.js'
import timer from '@/commons/utils/timer.js'
import go from '@/commons/utils/go.js'
import emit from '@/commons/utils/emit.js'

const jeepayPopupInputRef = ref()
const paymentSuccessRef = ref()
const jeepayBizinfoSelect = ref()

const vdata = reactive({
  payRemark: '', // 支付备注
  payAmount: 0, // 支付金额
  store: {}, //选择的门店
  isUnload: false, // 页面是否已销毁。
  isOpenScan: false, // 是否直接打开相机
})

// 页面销毁需要将 定时任务结束。
onUnload(() => {
  vdata.isUnload = true
  uni.$off(emit.ENAME_E_PAY_SCAN)
  uni.$off(emit.ENAME_RESET_PAY_AMOUNT)
})

onShow(() => {
  if (vdata.isOpenScan) {
    // 打开相机
    funObj.scan()
    vdata.isOpenScan = false
  } else {
    // 其他页面进入， 需要金额初始化。
    // 调起扫一扫， 会重新 onShow， 暂时不重置金额。
    // vdata.payAmount = 0; // 金额初始化
  }
})

// 监听扫一扫, 之后需要在 onShow中调用。
uni.$on(emit.ENAME_E_PAY_SCAN, function (data) {
  vdata.isOpenScan = true
})
uni.$on(emit.ENAME_RESET_PAY_AMOUNT, function (data) {
  vdata.payAmount = 0
  vdata.payRemark = ''
})

function reqTableDataByStoreFunc(params) {
  return reqLoad.list(API_URL_MCH_STORE_LIST, params)
}

// 预先检查
function preCheckFunc(callbackFunc) {
  if (isNaN(vdata.payAmount) || vdata.payAmount <= 0) {
    infoBox.showToast('请输入金额')
    return false
  }

  if (!vdata.store.storeId) {
    infoBox.showToast('请选择门店')
    selectedStore().then(() => {
      if (callbackFunc) {
        callbackFunc()
      }
    })
    return false
  }

  return true
}

const funObj = {
  scan: () => {
    if (!preCheckFunc(funObj.scan)) {
      return false
    }
    uni.scanCode().then(({ result }) => {
      // 调起支付
      $appPay(vdata.store.storeId, vdata.payAmount, vdata.payRemark, 'AUTO_BAR', result).then(({ bizData }) => {
        processPayData(bizData, true)
      })
    })
  },
  code: () => {
    if (!preCheckFunc(funObj.code)) {
      return false
    }
    // 调起支付
    $appPay(vdata.store.storeId, vdata.payAmount, vdata.payRemark, 'QR_CASHIER').then(({ bizData }) => {
      // 处理支付结果
      processPayData(bizData, false)
    })
  },
}

// 选择门店
const selectedStore = () => {
  return jeepayBizinfoSelect.value.open(vdata.store).then((selected) => {
    if (selected) {
      vdata.store = selected
      return Promise.resolve()
    } else {
      vdata.store = {}
      return Promise.reject()
    }
  })
}

// 处理调起下单接口的返回数据
function processPayData(bizData, isScan) {
  if (bizData.orderState == 2) {
    // 成功

    // 跳转到支付成功页面, 兼容payOrderInfo没有数据的情况。
    let payOrderInfo = Object.assign(bizData, { state: bizData.orderState, amount: vdata.payAmount * 100 })
    if (bizData.payOrderInfo) {
      payOrderInfo = JSON.parse(bizData.payOrderInfo)
    }
    vdata.payAmount = 0
    return paymentSuccessRef.value.open(payOrderInfo)
  } else if (bizData.orderState == 3) {
    // 成功

    // 失败
    return infoBox.showToast('失败：' + bizData.errMsg, 3)
  } else {
    // 聚合二维码方式 - 显示弹层
    if (!isScan) {
      return go.to('PAGES_QR_CASHIER', { qrImgUrl: bizData.payData, payOrderId: bizData.payOrderId, payAmount: vdata.payAmount })
    }

    // 仅scan 需要 轮询查单
    return orderPollingByScan(bizData.payOrderId)
  }
}

// 轮询查单 ( 扫一扫方式 )
function orderPollingByScan(payOrderId) {
  // 总共查询几次
  let allCount = 10

  timer.startTimeoutTask(2, allCount, (subTime) => {
    // 页面已销毁。
    if (vdata.isUnload) {
      return false
    }

    infoBox.showLoading(`等待付款, 第[${allCount - subTime}/${allCount}]次查单中...`)

    // 任务结束
    if (subTime <= 0) {
      return infoBox.showToast('请于订单列表查询结果').then(() => {
        emit.pageEmit(emit.ENAME_REF_PAY_ORDER) // 刷新订单数据
        go.to('PAGES_PAY_ORDER', {}, go.GO_TYPE_SWITCHTAB)
      })
    }

    return req.getById(API_URL_PAY_ORDER_LIST, payOrderId).then(({ bizData }) => {
      switch (bizData.state) {
        case 2:
          infoBox.showSuccessToast('支付成功')
          paymentSuccessRef.value.open(bizData)
          return Promise.reject()
          break
        case 3:
          infoBox.showToast('支付失败：' + bizData.errMsg, 3)
          return Promise.reject()
          break
        case 4:
          infoBox.showErrorToast('订单撤销')
          return Promise.reject()
          break
        default:
          return Promise.resolve()
          break
      }
    })
  })
}

const boardDown = (key) => {
  if (['scan', 'code'].includes(key)) return funObj[key]()
}
// 成功清除数据
const resetData = () => {
  vdata.payAmount = 0
  vdata.payRemark = ''
}
</script>

<style lang="scss" scoped>
.quick-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: calc(100vh - 90rpx);
  .quick-money {
    margin: 0 auto;
    margin-top: 50rpx;
    width: 630rpx;
    border-bottom: 1rpx solid rgba(0, 0, 0, 0.2);
    .quick-title {
      color: rgba(0, 0, 0, 0.5);
      font-size: 30rpx;
    }
    .quick-input {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 130rpx;
      margin-top: 10rpx;
      .quick-number {
        flex: 1;
        font-size: 60rpx;
        font-weight: 500;
      }
      text {
        align-self: flex-end;
        transform: translateY(-30rpx);
        font-weight: 700;
      }
    }
  }
  .quick-remarks-wrapper {
    margin-top: 58rpx;
    text-align: center;
    font-size: 30rpx;
    color: $J-color-t29;
  }
}
</style>
